home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / lib / python2.5 / idlelib / AutoCompleteWindow.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-29  |  12KB  |  343 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.5)
  3.  
  4. '''
  5. An auto-completion window for IDLE, used by the AutoComplete extension
  6. '''
  7. from Tkinter import *
  8. from MultiCall import MC_SHIFT
  9. import AutoComplete
  10. HIDE_VIRTUAL_EVENT_NAME = '<<autocompletewindow-hide>>'
  11. HIDE_SEQUENCES = ('<FocusOut>', '<ButtonPress>')
  12. KEYPRESS_VIRTUAL_EVENT_NAME = '<<autocompletewindow-keypress>>'
  13. KEYPRESS_SEQUENCES = ('<Key>', '<Key-BackSpace>', '<Key-Return>', '<Key-Tab>', '<Key-Up>', '<Key-Down>', '<Key-Home>', '<Key-End>', '<Key-Prior>', '<Key-Next>')
  14. KEYRELEASE_VIRTUAL_EVENT_NAME = '<<autocompletewindow-keyrelease>>'
  15. KEYRELEASE_SEQUENCE = '<KeyRelease>'
  16. LISTUPDATE_SEQUENCE = '<B1-ButtonRelease>'
  17. WINCONFIG_SEQUENCE = '<Configure>'
  18. DOUBLECLICK_SEQUENCE = '<B1-Double-ButtonRelease>'
  19.  
  20. class AutoCompleteWindow:
  21.     
  22.     def __init__(self, widget):
  23.         self.widget = widget
  24.         self.autocompletewindow = None
  25.         self.listbox = None
  26.         self.scrollbar = None
  27.         self.origselforeground = None
  28.         self.origselbackground = None
  29.         self.completions = None
  30.         self.morecompletions = None
  31.         self.mode = None
  32.         self.start = None
  33.         self.startindex = None
  34.         self.lasttypedstart = None
  35.         self.userwantswindow = None
  36.         self.hideid = None
  37.         self.keypressid = None
  38.         self.listupdateid = None
  39.         self.winconfigid = None
  40.         self.keyreleaseid = None
  41.         self.doubleclickid = None
  42.         self.lastkey_was_tab = False
  43.  
  44.     
  45.     def _change_start(self, newstart):
  46.         i = 0
  47.         while i < len(self.start) and i < len(newstart) and self.start[i] == newstart[i]:
  48.             i += 1
  49.         if i < len(self.start):
  50.             self.widget.delete('%s+%dc' % (self.startindex, i), '%s+%dc' % (self.startindex, len(self.start)))
  51.         
  52.         if i < len(newstart):
  53.             self.widget.insert('%s+%dc' % (self.startindex, i), newstart[i:])
  54.         
  55.         self.start = newstart
  56.  
  57.     
  58.     def _binary_search(self, s):
  59.         '''Find the first index in self.completions where completions[i] is
  60.         greater or equal to s, or the last index if there is no such
  61.         one.'''
  62.         i = 0
  63.         j = len(self.completions)
  64.         while j > i:
  65.             m = (i + j) // 2
  66.             if self.completions[m] >= s:
  67.                 j = m
  68.                 continue
  69.             i = m + 1
  70.         return min(i, len(self.completions) - 1)
  71.  
  72.     
  73.     def _complete_string(self, s):
  74.         '''Assuming that s is the prefix of a string in self.completions,
  75.         return the longest string which is a prefix of all the strings which
  76.         s is a prefix of them. If s is not a prefix of a string, return s.'''
  77.         first = self._binary_search(s)
  78.         if self.completions[first][:len(s)] != s:
  79.             return s
  80.         
  81.         i = first + 1
  82.         j = len(self.completions)
  83.         while j > i:
  84.             m = (i + j) // 2
  85.             if self.completions[m][:len(s)] != s:
  86.                 j = m
  87.                 continue
  88.             i = m + 1
  89.         last = i - 1
  90.         i = len(s)
  91.         while len(self.completions[first]) > i and len(self.completions[last]) > i and self.completions[first][i] == self.completions[last][i]:
  92.             i += 1
  93.         return self.completions[first][:i]
  94.  
  95.     
  96.     def _selection_changed(self):
  97.         '''Should be called when the selection of the Listbox has changed.
  98.         Updates the Listbox display and calls _change_start.'''
  99.         cursel = int(self.listbox.curselection()[0])
  100.         self.listbox.see(cursel)
  101.         lts = self.lasttypedstart
  102.         selstart = self.completions[cursel]
  103.         if self._binary_search(lts) == cursel:
  104.             newstart = lts
  105.         else:
  106.             i = 0
  107.             while i < len(lts) and i < len(selstart) and lts[i] == selstart[i]:
  108.                 i += 1
  109.             newstart = selstart[:i]
  110.         self._change_start(newstart)
  111.         if self.completions[cursel][:len(self.start)] == self.start:
  112.             self.listbox.configure(selectbackground = self.origselbackground, selectforeground = self.origselforeground)
  113.         else:
  114.             self.listbox.configure(selectbackground = self.listbox.cget('bg'), selectforeground = self.listbox.cget('fg'))
  115.             if self.morecompletions:
  116.                 self.completions = self.morecompletions
  117.                 self.morecompletions = None
  118.                 self.listbox.delete(0, END)
  119.                 for item in self.completions:
  120.                     self.listbox.insert(END, item)
  121.                 
  122.                 self.listbox.select_set(self._binary_search(self.start))
  123.                 self._selection_changed()
  124.             
  125.  
  126.     
  127.     def show_window(self, comp_lists, index, complete, mode, userWantsWin):
  128.         """Show the autocomplete list, bind events.
  129.         If complete is True, complete the text, and if there is exactly one
  130.         matching completion, don't open a list."""
  131.         (self.completions, self.morecompletions) = comp_lists
  132.         self.mode = mode
  133.         self.startindex = self.widget.index(index)
  134.         self.start = self.widget.get(self.startindex, 'insert')
  135.         if complete:
  136.             completed = self._complete_string(self.start)
  137.             self._change_start(completed)
  138.             i = self._binary_search(completed)
  139.             if self.completions[i] == completed:
  140.                 pass
  141.             None if i == len(self.completions) - 1 or self.completions[i + 1][:len(completed)] != completed else self.completions[i + 1][:len(completed)] != completed
  142.         
  143.         self.userwantswindow = userWantsWin
  144.         self.lasttypedstart = self.start
  145.         self.autocompletewindow = acw = Toplevel(self.widget)
  146.         acw.wm_geometry('+10000+10000')
  147.         acw.wm_overrideredirect(1)
  148.         
  149.         try:
  150.             acw.tk.call('::tk::unsupported::MacWindowStyle', 'style', acw._w, 'help', 'noActivates')
  151.         except TclError:
  152.             pass
  153.  
  154.         self.scrollbar = scrollbar = Scrollbar(acw, orient = VERTICAL)
  155.         self.listbox = listbox = Listbox(acw, yscrollcommand = scrollbar.set, exportselection = False, bg = 'white')
  156.         for item in self.completions:
  157.             listbox.insert(END, item)
  158.         
  159.         self.origselforeground = listbox.cget('selectforeground')
  160.         self.origselbackground = listbox.cget('selectbackground')
  161.         scrollbar.config(command = listbox.yview)
  162.         scrollbar.pack(side = RIGHT, fill = Y)
  163.         listbox.pack(side = LEFT, fill = BOTH, expand = True)
  164.         self.listbox.select_set(self._binary_search(self.start))
  165.         self._selection_changed()
  166.         self.hideid = self.widget.bind(HIDE_VIRTUAL_EVENT_NAME, self.hide_event)
  167.         for seq in HIDE_SEQUENCES:
  168.             self.widget.event_add(HIDE_VIRTUAL_EVENT_NAME, seq)
  169.         
  170.         self.keypressid = self.widget.bind(KEYPRESS_VIRTUAL_EVENT_NAME, self.keypress_event)
  171.         for seq in KEYPRESS_SEQUENCES:
  172.             self.widget.event_add(KEYPRESS_VIRTUAL_EVENT_NAME, seq)
  173.         
  174.         self.keyreleaseid = self.widget.bind(KEYRELEASE_VIRTUAL_EVENT_NAME, self.keyrelease_event)
  175.         self.widget.event_add(KEYRELEASE_VIRTUAL_EVENT_NAME, KEYRELEASE_SEQUENCE)
  176.         self.listupdateid = listbox.bind(LISTUPDATE_SEQUENCE, self.listselect_event)
  177.         self.winconfigid = acw.bind(WINCONFIG_SEQUENCE, self.winconfig_event)
  178.         self.doubleclickid = listbox.bind(DOUBLECLICK_SEQUENCE, self.doubleclick_event)
  179.  
  180.     
  181.     def winconfig_event(self, event):
  182.         if not self.is_active():
  183.             return None
  184.         
  185.         acw = self.autocompletewindow
  186.         self.widget.see(self.startindex)
  187.         (x, y, cx, cy) = self.widget.bbox(self.startindex)
  188.         acw.wm_geometry('+%d+%d' % (x + self.widget.winfo_rootx(), y + self.widget.winfo_rooty() - acw.winfo_height()))
  189.  
  190.     
  191.     def hide_event(self, event):
  192.         if not self.is_active():
  193.             return None
  194.         
  195.         self.hide_window()
  196.  
  197.     
  198.     def listselect_event(self, event):
  199.         if not self.is_active():
  200.             return None
  201.         
  202.         self.userwantswindow = True
  203.         cursel = int(self.listbox.curselection()[0])
  204.         self._change_start(self.completions[cursel])
  205.  
  206.     
  207.     def doubleclick_event(self, event):
  208.         cursel = int(self.listbox.curselection()[0])
  209.         self._change_start(self.completions[cursel])
  210.         self.hide_window()
  211.  
  212.     
  213.     def keypress_event(self, event):
  214.         if not self.is_active():
  215.             return None
  216.         
  217.         keysym = event.keysym
  218.         if hasattr(event, 'mc_state'):
  219.             state = event.mc_state
  220.         else:
  221.             state = 0
  222.         if keysym != 'Tab':
  223.             self.lastkey_was_tab = False
  224.         
  225.         if (len(keysym) == 1 and keysym in ('underscore', 'BackSpace') or self.mode == AutoComplete.COMPLETE_FILES or keysym in ('period', 'minus')) and not (state & ~MC_SHIFT):
  226.             if len(keysym) == 1:
  227.                 self._change_start(self.start + keysym)
  228.             elif keysym == 'underscore':
  229.                 self._change_start(self.start + '_')
  230.             elif keysym == 'period':
  231.                 self._change_start(self.start + '.')
  232.             elif keysym == 'minus':
  233.                 self._change_start(self.start + '-')
  234.             elif len(self.start) == 0:
  235.                 self.hide_window()
  236.                 return None
  237.             
  238.             self._change_start(self.start[:-1])
  239.             self.lasttypedstart = self.start
  240.             self.listbox.select_clear(0, int(self.listbox.curselection()[0]))
  241.             self.listbox.select_set(self._binary_search(self.start))
  242.             self._selection_changed()
  243.             return 'break'
  244.         elif keysym == 'Return':
  245.             self.hide_window()
  246.             return None
  247.         elif not self.mode == AutoComplete.COMPLETE_ATTRIBUTES or keysym in ('period', 'space', 'parenleft', 'parenright', 'bracketleft', 'bracketright'):
  248.             if (self.mode == AutoComplete.COMPLETE_FILES or keysym in ('slash', 'backslash', 'quotedbl', 'apostrophe')) and not (state & ~MC_SHIFT):
  249.                 cursel = int(self.listbox.curselection()[0])
  250.                 if self.completions[cursel][:len(self.start)] == self.start:
  251.                     if self.mode == AutoComplete.COMPLETE_ATTRIBUTES or self.start:
  252.                         self._change_start(self.completions[cursel])
  253.                     
  254.                 self.hide_window()
  255.                 return None
  256.             elif keysym in ('Home', 'End', 'Prior', 'Next', 'Up', 'Down') and not state:
  257.                 self.userwantswindow = True
  258.                 cursel = int(self.listbox.curselection()[0])
  259.                 if keysym == 'Home':
  260.                     newsel = 0
  261.                 elif keysym == 'End':
  262.                     newsel = len(self.completions) - 1
  263.                 elif keysym in ('Prior', 'Next'):
  264.                     jump = self.listbox.nearest(self.listbox.winfo_height()) - self.listbox.nearest(0)
  265.                     if keysym == 'Prior':
  266.                         newsel = max(0, cursel - jump)
  267.                     elif not keysym == 'Next':
  268.                         raise AssertionError
  269.                     newsel = min(len(self.completions) - 1, cursel + jump)
  270.                 elif keysym == 'Up':
  271.                     newsel = max(0, cursel - 1)
  272.                 elif not keysym == 'Down':
  273.                     raise AssertionError
  274.                 newsel = min(len(self.completions) - 1, cursel + 1)
  275.                 self.listbox.select_clear(cursel)
  276.                 self.listbox.select_set(newsel)
  277.                 self._selection_changed()
  278.                 self._change_start(self.completions[newsel])
  279.                 return 'break'
  280.             elif keysym == 'Tab' and not state:
  281.                 if self.lastkey_was_tab:
  282.                     cursel = int(self.listbox.curselection()[0])
  283.                     self._change_start(self.completions[cursel])
  284.                     self.hide_window()
  285.                     return 'break'
  286.                 else:
  287.                     self.userwantswindow = True
  288.                     self.lastkey_was_tab = True
  289.                     return None
  290.             elif []([], [ keysym.find(s) != -1 for s in ('Shift', 'Control', 'Alt', 'Meta', 'Command', 'Option') ]):
  291.                 return None
  292.             else:
  293.                 self.hide_window()
  294.                 return None
  295.  
  296.     
  297.     def keyrelease_event(self, event):
  298.         if not self.is_active():
  299.             return None
  300.         
  301.         if self.widget.index('insert') != self.widget.index('%s+%dc' % (self.startindex, len(self.start))):
  302.             self.hide_window()
  303.         
  304.  
  305.     
  306.     def is_active(self):
  307.         return self.autocompletewindow is not None
  308.  
  309.     
  310.     def complete(self):
  311.         self._change_start(self._complete_string(self.start))
  312.  
  313.     
  314.     def hide_window(self):
  315.         if not self.is_active():
  316.             return None
  317.         
  318.         for seq in HIDE_SEQUENCES:
  319.             self.widget.event_delete(HIDE_VIRTUAL_EVENT_NAME, seq)
  320.         
  321.         self.widget.unbind(HIDE_VIRTUAL_EVENT_NAME, self.hideid)
  322.         self.hideid = None
  323.         for seq in KEYPRESS_SEQUENCES:
  324.             self.widget.event_delete(KEYPRESS_VIRTUAL_EVENT_NAME, seq)
  325.         
  326.         self.widget.unbind(KEYPRESS_VIRTUAL_EVENT_NAME, self.keypressid)
  327.         self.keypressid = None
  328.         self.widget.event_delete(KEYRELEASE_VIRTUAL_EVENT_NAME, KEYRELEASE_SEQUENCE)
  329.         self.widget.unbind(KEYRELEASE_VIRTUAL_EVENT_NAME, self.keyreleaseid)
  330.         self.keyreleaseid = None
  331.         self.listbox.unbind(LISTUPDATE_SEQUENCE, self.listupdateid)
  332.         self.listupdateid = None
  333.         self.autocompletewindow.unbind(WINCONFIG_SEQUENCE, self.winconfigid)
  334.         self.winconfigid = None
  335.         self.scrollbar.destroy()
  336.         self.scrollbar = None
  337.         self.listbox.destroy()
  338.         self.listbox = None
  339.         self.autocompletewindow.destroy()
  340.         self.autocompletewindow = None
  341.  
  342.  
  343.